package com.hfzy.ihk.web.ivr.support.disruptor;

import com.hfzy.ihk.web.ivr.constant.Constants;
import com.hfzy.ihk.web.ivr.support.disruptor.base.DisruptorEvent;
import com.lmax.disruptor.RingBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Created by Administrator on 2016/5/16.
 * @author wws
 * disruptor并发框架支持类
 *
 * 需要使用disruptor的类继承此类
 *
 */
public abstract class DisruptorSupport<T extends Object,E extends DisruptorEvent<T>> {

    private static final Logger logger = LoggerFactory.getLogger(DisruptorSupport.class);



    /**
     * 使用disruptorInitBean中的一个ringBufferDisruptorEvent
     * */
    protected abstract RingBuffer<E> useRingBuffer(T data);

    /**
     * 发布数据到ringBuffer
     *
     * 成功返回0
     * 失败返回-1
     *
     * */
    protected String putInRingBuffer(T data){

        RingBuffer<E> ringBuffer = useRingBuffer(data);
        // 发布事件；
        long sequence = ringBuffer.next();//请求下一个事件序号(竞争)；

        try {
            E event = ringBuffer.get(sequence);//获取该序号对应的事件对象；
            event.setData(data);
        } finally{
            ringBuffer.publish(sequence);//发布事件；

            ringBuffer = null;
        }
        return Constants.SUCCESS;
    }

    public void checkRingBufferUse(RingBuffer<E> ringBuffer,String fromRoute){
        // 检测ringBufferCallOut剩余容量
        long remainingCapacity = ringBuffer.remainingCapacity();
        long bufferSize = ringBuffer.getBufferSize();

        if(remainingCapacity==0) {
            logger.warn("{},消费者最小序列号：{},当前指针：{}",fromRoute,ringBuffer.getMinimumGatingSequence(),ringBuffer.getCursor());
        }else if(bufferSize-remainingCapacity >= 1000){
            logger.warn("{},通话状态队列超过50%,bufferSize:{},remainingCapacity:{}",fromRoute,bufferSize,remainingCapacity);
        }
    }
}
